package com.xls.aclservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xls.aclservice.entity.SysMenu;
import com.xls.aclservice.mapper.SysMenuMapper;
import com.xls.aclservice.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xls
 * @since 2021-03-23
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public List<SysMenu> getMenus() {
        List<SysMenu> sysMenuList = this.list(new QueryWrapper<SysMenu>().eq("status", true));
        List<SysMenu> build = build(sysMenuList);
        return build;
    }

    @Override
    public List<SysMenu> getMenus(Long id) {
        List<SysMenu> sysMenuList = sysMenuMapper.getMenusById(id);
        sysMenuList = sysMenuList.stream().filter(menu -> !menu.getType().equals(2)).collect(Collectors.toList());
        return build(sysMenuList);
    }

    @Override
    public void removeMenu(SysMenu sysMenu) {
        List<Long> menuIds = getMenuIds(sysMenu);
        this.update(new UpdateWrapper<SysMenu>().in("id", menuIds).set("status", sysMenu.getStatus()));
    }

    private List<Long> getMenuIds(SysMenu sysMenu) {
        ArrayList<Long> menuIds = new ArrayList<>();
        menuIds.add(sysMenu.getId());
        if (sysMenu.getChildren().size() > 0) {
            List<SysMenu> children = sysMenu.getChildren();
            setMenuIds(menuIds, children);
        }
        return menuIds;
    }

    private void setMenuIds(ArrayList<Long> menuIds, List<SysMenu> children) {
        for (SysMenu child : children) {
            menuIds.add(child.getId());
            if (child.getChildren().size() > 0) {
                List<SysMenu> childrenSysMenus = child.getChildren();
                setMenuIds(menuIds, childrenSysMenus);
            }
        }
    }

    public static List<SysMenu> build(List<SysMenu> nodes) {

        //得到一级菜单
        List<SysMenu> rootSysMenus = new ArrayList<>();
        for (SysMenu node : nodes) {
            //如果parentId为0则是一级菜单
            if (node.getParentId() == 0) {
                rootSysMenus.add(node);
            }
        }

        //对一级菜单排序
        rootSysMenus.sort(Comparator.comparing(SysMenu::getSort));

        //设置一级菜单的子菜单
        for (SysMenu node : rootSysMenus) {
            node.setChildren(getChild(node.getId(), nodes));
        }

        return rootSysMenus;
    }

    /**
     * 获取子菜单
     * @param id 菜单id
     * @param nodes menu表
     * @return
     */
    private static List<SysMenu> getChild(Long id, List<SysMenu> nodes) {

        //子菜单
        List<SysMenu> childList = new ArrayList<>();

        //遍历menu表判断当前节点的id和menu表的父id是否相同 如果相同就将Menu加入到list中
        for (SysMenu node : nodes) {
            if (node.getParentId().equals(id)) {
                childList.add(node);
            }
        }

        //如果子菜单中没有Menu就直接返回空list 防止死循环
        if (childList.size() == 0) {
            return new ArrayList<>();
        }

        //递归遍历childList子菜单中的每个Menu是否还有子菜单
        for (SysMenu node : childList) {
            node.setChildren(getChild(node.getId(), nodes));
        }

        //最后将其进行排序
        childList.sort(Comparator.comparing(SysMenu::getSort));

        return childList;

    }
}
